package com.aim.analysis.yoachim;

import com.aim.analysis.records.*;
import com.aim.analysis.records.bean.PerformanceData;
import com.aim.util.Pair;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * User: Avraham Shvartzon
 * Date: 7/7/14
 */
public class GameSplitter {

    public static Game[] split(Game game, double percent){
        Game[] games = new Game[2];
        games[0] = new Game(game.getKey());
        games[1] = new Game(game.getKey());

        int gameLength = game.getGameLength();
        int splitTime = (int) (gameLength * 0.5);

        Set<GameRecord> records = game.getRecords();

        Pair<List<GameRecord>, List<GameRecord>> recordLists = new Pair<List<GameRecord>, List<GameRecord>>(
                new ArrayList<GameRecord>(),
                new ArrayList<GameRecord>()
        );
        splitRecords(recordLists, splitTime, records);

        // reorder the sequence numbers

        // split performance data and add performance records
        PerformanceData[] perfData = splitPerformanceData(game, splitTime);
        addPerformanceRecord(recordLists.a, perfData[0]);
        addPerformanceRecord(recordLists.b, perfData[1]);

        // add start end finish records
        addEndRecord(recordLists.a, splitTime);
        addStartRecord(recordLists.b, splitTime);


        // reorder the sequence numbers
        reorderSequenceNumber(recordLists.a);
        reorderSequenceNumber(recordLists.b);


        addRecordsToGame(games[0],recordLists.a);
        addRecordsToGame(games[1],recordLists.b);


        return games;
    }

    private static void addRecordsToGame(Game game, List<GameRecord> records) {
        for (GameRecord record : records) {
            game.addRecord(record);
        }
        game.postProcessing();
    }

    private static void reorderSequenceNumber(List<GameRecord> a) {
        for (int i = 0; i < a.size(); i++) {
            GameRecord record = a.get(i);
            record.sequenceNumber = i + 1;
        }
    }

    private static void addStartRecord(List<GameRecord> recordList, int splitTime) {
        GameRecord record = recordList.get(recordList.size() - 1);
        GameRecord gameStartedRecord = new GameRecord(record);
        gameStartedRecord.recordType = RecordType.gameStarted;
        gameStartedRecord.time = splitTime;
        recordList.add(0,gameStartedRecord);
    }

    private static void addEndRecord(List<GameRecord> recordList, int splitTime) {
        GameRecord record = recordList.get(recordList.size() - 1);
        GameRecord endRecord = new GameRecord(record);
        endRecord.recordType = RecordType.gameEnd;
        endRecord.time = splitTime;
        recordList.add(endRecord);
    }

    private static void addPerformanceRecord(List<GameRecord> recordList, PerformanceData performanceData) {
        GameRecord firstRecord = recordList.get(0);
        GameRecord perfRecord = new GameRecord(firstRecord);
        perfRecord.recordType = RecordType.meteorSummery;
        perfRecord.setPerformanceData(performanceData);
        recordList.add(1,perfRecord);
    }

    private static PerformanceData[] splitPerformanceData(Game game, int splitTime) {
        PerformanceDataCollector perfCollector = new PerformanceDataCollector();

        List<GameRecord> perfRecords = game.getRecords(RecordType.meteorSummery);
        for (GameRecord perfRecord : perfRecords) {
            PerformanceData performanceData = perfRecord.getPerformanceData();
            if (performanceData != null){
                perfCollector.addPerformanceData(performanceData);
            }
        }
        return perfCollector.split(splitTime);
    }


    private static void splitRecords(Pair<List<GameRecord>, List<GameRecord>> recordLists, int splitTime, Set<GameRecord> records) {
        for (GameRecord record : records) {
            if (record.recordType == RecordType.meteorSummery){
              continue;
            }
            List<GameRecord> recordList = (record.time < splitTime || record.recordType == RecordType.gameStarted) ? recordLists.a : recordLists.b;
            recordList.add(record);
        }
    }

    public static void main(String[] args) {
        List<Hit> hits = Hit.getHits("20140606");
        Hit hit = hits.get(0);
        Game game = hit.gameList.get(0);
        Game[] games = split(game, 0.5);

    }

}
